home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / misc / o-z / x-windows / mesa-amiwin / src / fog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-30  |  11.0 KB  |  414 lines

  1. /* fog.c */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995  Brian Paul  (brianp@ssec.wisc.edu)
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25. $Id: fog.c,v 1.9 1995/11/03 22:35:35 brianp Exp $
  26.  
  27. $Log: fog.c,v $
  28.  * Revision 1.9  1995/11/03  22:35:35  brianp
  29.  * replaced gl_fog_color_vertex with gl_fog_color_vertices
  30.  * replaced gl_fog_index_vertex with gl_fog_index_vertices
  31.  *
  32.  * Revision 1.8  1995/07/20  15:35:11  brianp
  33.  * added type casts to stop warnings with Sun's cc
  34.  *
  35.  * Revision 1.7  1995/06/12  15:41:04  brianp
  36.  * removed debugging printf's
  37.  *
  38.  * Revision 1.6  1995/06/12  15:33:54  brianp
  39.  * changed color arrays to GLubyte
  40.  * check for -eyez in gl_fog_index_pixels
  41.  *
  42.  * Revision 1.5  1995/05/22  21:02:41  brianp
  43.  * Release 1.2
  44.  *
  45.  * Revision 1.4  1995/03/04  19:29:44  brianp
  46.  * 1.1 beta revision
  47.  *
  48.  * Revision 1.3  1995/02/27  22:48:50  brianp
  49.  * modified for PB
  50.  *
  51.  * Revision 1.2  1995/02/26  22:58:24  brianp
  52.  * fixed glFogi
  53.  *
  54.  * Revision 1.1  1995/02/24  14:23:03  brianp
  55.  * Initial revision
  56.  *
  57.  */
  58.  
  59.  
  60. #include <math.h>
  61. #include <stdlib.h>
  62. #include "context.h"
  63. #include "list.h"
  64. #include "macros.h"
  65.  
  66.  
  67.  
  68. void gl_fog( GLenum pname, const GLfloat *params )
  69. {
  70.    GLenum m;
  71.  
  72.    switch (pname) {
  73.       case GL_FOG_MODE:
  74.          m = (GLenum) (GLint) *params;
  75.      if (m==GL_LINEAR || m==GL_EXP || m==GL_EXP2) {
  76.         CC.Fog.Mode = m;
  77.      }
  78.      else {
  79.         gl_error( GL_INVALID_ENUM, "glFog" );
  80.      }
  81.      break;
  82.       case GL_FOG_DENSITY:
  83.      if (*params<0.0) {
  84.         gl_error( GL_INVALID_VALUE, "glFog" );
  85.      }
  86.      else {
  87.         CC.Fog.Density = *params;
  88.      }
  89.      break;
  90.       case GL_FOG_START:
  91.      CC.Fog.Start = *params;
  92.      break;
  93.       case GL_FOG_END:
  94.      CC.Fog.End = *params;
  95.      break;
  96.       case GL_FOG_INDEX:
  97.      CC.Fog.Index = *params;
  98.      break;
  99.       case GL_FOG_COLOR:
  100.      CC.Fog.Color[0] = params[0];
  101.      CC.Fog.Color[1] = params[1];
  102.      CC.Fog.Color[2] = params[2];
  103.      CC.Fog.Color[3] = params[3];
  104.          break;
  105.       default:
  106.          gl_error( GL_INVALID_ENUM, "glFog" );
  107.    }
  108. }
  109.  
  110.  
  111.  
  112. void glFogf( GLenum pname, GLfloat param )
  113. {
  114.    if (CC.ExecuteFlag) {
  115.       gl_fog( pname, ¶m );
  116.    }
  117.    if (CC.CompileFlag) {
  118.       gl_save_fog( pname, ¶m );
  119.    }
  120. }
  121.  
  122.  
  123.  
  124. void glFogi( GLenum pname, GLint param )
  125. {
  126.    GLfloat p;
  127.  
  128.    p = (GLfloat) param;
  129.  
  130.    if (CC.ExecuteFlag) {
  131.       gl_fog( pname, &p );
  132.    }
  133.    if (CC.CompileFlag) {
  134.       gl_save_fog( pname, &p );
  135.    }
  136. }
  137.  
  138.  
  139.  
  140. void glFogfv( GLenum pname, const GLfloat *params )
  141. {
  142.    if (CC.ExecuteFlag) {
  143.       gl_fog( pname, params );
  144.    }
  145.    if (CC.CompileFlag) {
  146.       gl_save_fog( pname, params );
  147.    }
  148. }
  149.  
  150.  
  151.  
  152. void glFogiv( GLenum pname, const GLint *params )
  153. {
  154.    GLfloat p[4];
  155.  
  156.    switch (pname) {
  157.       case GL_FOG_MODE:
  158.       case GL_FOG_DENSITY:
  159.       case GL_FOG_START:
  160.       case GL_FOG_END:
  161.       case GL_FOG_INDEX:
  162.          p[0] = (GLfloat) *params;
  163.      break;
  164.       case GL_FOG_COLOR:
  165.      p[0] = INT_TO_FLOAT( params[0] );
  166.      p[1] = INT_TO_FLOAT( params[1] );
  167.      p[2] = INT_TO_FLOAT( params[2] );
  168.      p[3] = INT_TO_FLOAT( params[3] );
  169.      break;
  170.       default:
  171.      gl_error( GL_INVALID_ENUM, "glFogi" );
  172.      return;
  173.    }
  174.    if (CC.ExecuteFlag) {
  175.       gl_fog( pname, p );
  176.    }
  177.    if (CC.CompileFlag) {
  178.       gl_save_fog( pname, p );
  179.    }
  180. }
  181.  
  182.  
  183.  
  184. /*
  185.  * Compute the fogged color for an array of vertices.
  186.  * Input:  n - number of vertices
  187.  *         v - array of vertices
  188.  *         color - the original vertex colors
  189.  * Output:  color - the fogged colors
  190.  */
  191. void gl_fog_color_vertices( GLuint n, GLfloat v[][4], GLfloat color[][4] )
  192. {
  193.    GLuint i;
  194.    GLfloat d;
  195.    GLfloat fogr = CC.Fog.Color[0];
  196.    GLfloat fogg = CC.Fog.Color[1];
  197.    GLfloat fogb = CC.Fog.Color[2];
  198.    GLfloat foga = CC.Fog.Color[3];
  199.  
  200.    switch (CC.Fog.Mode) {
  201.       case GL_LINEAR:
  202.          d = 1.0F / (CC.Fog.End - CC.Fog.Start);
  203.          for (i=0;i<n;i++) {
  204.             GLfloat f = (CC.Fog.End - ABS(v[i][2])) * d;
  205.             f = CLAMP( f, 0.0F, 1.0F );
  206.             color[i][0] = f * color[i][0] + (1.0F-f) * fogr;
  207.             color[i][1] = f * color[i][1] + (1.0F-f) * fogg;
  208.             color[i][2] = f * color[i][2] + (1.0F-f) * fogb;
  209.             color[i][3] = f * color[i][3] + (1.0F-f) * foga;
  210.          }
  211.      break;
  212.       case GL_EXP:
  213.          d = -CC.Fog.Density;
  214.          for (i=0;i<n;i++) {
  215.             GLfloat f = exp( d * ABS(v[i][2]) );
  216.             f = CLAMP( f, 0.0F, 1.0F );
  217.             color[i][0] = f * color[i][0] + (1.0F-f) * fogr;
  218.             color[i][1] = f * color[i][1] + (1.0F-f) * fogg;
  219.             color[i][2] = f * color[i][2] + (1.0F-f) * fogb;
  220.             color[i][3] = f * color[i][3] + (1.0F-f) * foga;
  221.          }
  222.      break;
  223.       case GL_EXP2:
  224.          d = -(CC.Fog.Density*CC.Fog.Density);
  225.          for (i=0;i<n;i++) {
  226.             GLfloat z = ABS(v[i][2]);
  227.             GLfloat f = exp( d * z*z );
  228.             f = CLAMP( f, 0.0F, 1.0F );
  229.             color[i][0] = f * color[i][0] + (1.0F-f) * fogr;
  230.             color[i][1] = f * color[i][1] + (1.0F-f) * fogg;
  231.             color[i][2] = f * color[i][2] + (1.0F-f) * fogb;
  232.             color[i][3] = f * color[i][3] + (1.0F-f) * foga;
  233.          }
  234.      break;
  235.       default:
  236.          abort();
  237.    }
  238. }
  239.  
  240.  
  241.  
  242.  
  243.  
  244. /*
  245.  * Compute the fogged color indexes for an array of vertices.
  246.  * Input:  n - number of vertices
  247.  *         v - array of vertices
  248.  * In/Out: indx - array of vertex color indexes
  249.  */
  250. void gl_fog_index_vertices( GLuint n, GLfloat v[][4], GLfloat indx[] )
  251. {
  252.    GLuint i;
  253.    GLfloat d;
  254.  
  255.    switch (CC.Fog.Mode) {
  256.       case GL_LINEAR:
  257.          d = 1.0F / (CC.Fog.End - CC.Fog.Start);
  258.          for (i=0;i<n;i++) {
  259.             GLfloat z = ABS(v[i][2]);
  260.             GLfloat f = (CC.Fog.End - z) * d;
  261.             f = CLAMP( f, 0.0F, 1.0F );
  262.             indx[i] = indx[i] + (1.0F-f) * CC.Fog.Index;
  263.          }
  264.      break;
  265.       case GL_EXP:
  266.          d = -CC.Fog.Density;
  267.          for (i=0;i<n;i++) {
  268.             GLfloat z = ABS(v[i][2]);
  269.             GLfloat f = exp( d * z );
  270.             f = CLAMP( f, 0.0F, 1.0F );
  271.             indx[i] = indx[i] + (1.0F-f) * CC.Fog.Index;
  272.          }
  273.      break;
  274.       case GL_EXP2:
  275.          d = -(CC.Fog.Density*CC.Fog.Density);
  276.          for (i=0;i<n;i++) {
  277.             GLfloat z = ABS(v[i][2]);
  278.             GLfloat f = exp( -d * z*z );
  279.             f = CLAMP( f, 0.0F, 1.0F );
  280.             indx[i] = indx[i] + (1.0F-f) * CC.Fog.Index;
  281.          }
  282.      break;
  283.       default:
  284.          abort();
  285.    }
  286. }
  287.  
  288.  
  289.  
  290.  
  291. /*
  292.  * Apply fog to an array of RGBA pixels.
  293.  * Input:  n - number of pixels
  294.  *         z - array of integer depth values
  295.  *         red, green, blue, alpha - pixel colors
  296.  * Output:  red, green, blue, alpha - fogged pixel colors
  297.  */
  298. void gl_fog_color_pixels( GLuint n, GLint z[], GLubyte red[],
  299.               GLubyte green[], GLubyte blue[], GLubyte alpha[] )
  300. {
  301.    /* TODO: optimize case when c = 1.0 and d = 0.0 */
  302.    GLfloat d = CC.ProjectionMatrix[14];
  303.    GLfloat c = CC.ProjectionMatrix[10];
  304.    GLfloat winz, ndcz, eyez, f;
  305.    GLuint i;
  306.  
  307.    GLint fog_red   = (GLint) (CC.Fog.Color[0] * CC.RedScale);
  308.    GLint fog_green = (GLint) (CC.Fog.Color[1] * CC.GreenScale);
  309.    GLint fog_blue  = (GLint) (CC.Fog.Color[2] * CC.BlueScale);
  310.    GLint fog_alpha = (GLint) (CC.Fog.Color[3] * CC.AlphaScale);
  311.  
  312.    switch (CC.Fog.Mode) {
  313.       case GL_LINEAR:
  314.          for (i=0;i<n;i++) {
  315.         winz = (GLfloat) z[i] / (GLfloat) MAX_DEPTH;
  316.         ndcz = (winz - CC.Viewport.Tz) / CC.Viewport.Sz;
  317.         eyez = -d / (c+ndcz);
  318.         if (eyez < 0.0)  eyez = -eyez;
  319.         f = (CC.Fog.End - eyez) / (CC.Fog.End - CC.Fog.Start);
  320.         f = CLAMP( f, 0.0F, 1.0F );
  321.         red[i]   = (GLint) (f * (GLfloat) red[i]   + (1.0F-f) * fog_red);
  322.         green[i] = (GLint) (f * (GLfloat) green[i] + (1.0F-f) * fog_green);
  323.         blue[i]  = (GLint) (f * (GLfloat) blue[i]  + (1.0F-f) * fog_blue);
  324.         alpha[i] = (GLint) (f * (GLfloat) alpha[i] + (1.0F-f) * fog_alpha);
  325.      }
  326.      break;
  327.       case GL_EXP:
  328.      for (i=0;i<n;i++) {
  329.         winz = (GLfloat) z[i] / (GLfloat) MAX_DEPTH;
  330.         ndcz = (winz - CC.Viewport.Tz) / CC.Viewport.Sz;
  331.         eyez = -d / (c+ndcz);
  332.         if (eyez < 0.0)  eyez = -eyez;
  333.         f = exp( -CC.Fog.Density * eyez );
  334.         f = CLAMP( f, 0.0F, 1.0F );
  335.         red[i]   = (GLint) (f * (GLfloat) red[i]   + (1.0F-f) * fog_red);
  336.         green[i] = (GLint) (f * (GLfloat) green[i] + (1.0F-f) * fog_green);
  337.         blue[i]  = (GLint) (f * (GLfloat) blue[i]  + (1.0F-f) * fog_blue);
  338.         alpha[i] = (GLint) (f * (GLfloat) alpha[i] + (1.0F-f) * fog_alpha);
  339.      }
  340.      break;
  341.       case GL_EXP2:
  342.      for (i=0;i<n;i++) {
  343.         winz = (GLfloat) z[i] / (GLfloat) MAX_DEPTH;
  344.         ndcz = (winz - CC.Viewport.Tz) / CC.Viewport.Sz;
  345.         eyez = -d / (c+ndcz);
  346.         if (eyez < 0.0)  eyez = -eyez;
  347.         f = exp( -(CC.Fog.Density*CC.Fog.Density * eyez*eyez) );
  348.         f = CLAMP( f, 0.0F, 1.0F );
  349.         red[i]   = (GLint) (f * (GLfloat) red[i]   + (1.0F-f) * fog_red);
  350.         green[i] = (GLint) (f * (GLfloat) green[i] + (1.0F-f) * fog_green);
  351.         blue[i]  = (GLint) (f * (GLfloat) blue[i]  + (1.0F-f) * fog_blue);
  352.         alpha[i] = (GLint) (f * (GLfloat) alpha[i] + (1.0F-f) * fog_alpha);
  353.      }
  354.      break;
  355.    }
  356. }
  357.  
  358.  
  359.  
  360.  
  361. /*
  362.  * Apply fog to an array of color index pixels.
  363.  * Input:  n - number of pixels
  364.  *         z - array of integer depth values
  365.  *         index - pixel color indexes
  366.  * Output:  index - fogged pixel color indexes
  367.  */
  368. void gl_fog_index_pixels( GLuint n, GLint z[], GLuint index[] )
  369. {
  370.    /* TODO: optimize case when c = 1.0 and d = 0.0 */
  371.    GLfloat d = CC.ProjectionMatrix[14];
  372.    GLfloat c = CC.ProjectionMatrix[10];
  373.    GLfloat winz, ndcz, eyez, f;
  374.    GLuint i;
  375.  
  376.    switch (CC.Fog.Mode) {
  377.       case GL_LINEAR:
  378.          for (i=0;i<n;i++) {
  379.         winz = (GLfloat) z[i] / (GLfloat) MAX_DEPTH;
  380.         ndcz = (winz - CC.Viewport.Tz) / CC.Viewport.Sz;
  381.         eyez = -d / (c+ndcz);
  382.         if (eyez < 0.0)  eyez = -eyez;
  383.         f = (CC.Fog.End - eyez) / (CC.Fog.End - CC.Fog.Start);
  384.         f = CLAMP( f, 0.0F, 1.0F );
  385.         index[i] = (GLuint) ((GLfloat) index[i] + (1.0F-f) * CC.Fog.Index);
  386.      }
  387.      break;
  388.       case GL_EXP:
  389.          for (i=0;i<n;i++) {
  390.         winz = (GLfloat) z[i] / (GLfloat) MAX_DEPTH;
  391.         ndcz = (winz - CC.Viewport.Tz) / CC.Viewport.Sz;
  392.         eyez = -d / (c+ndcz);
  393.         if (eyez < 0.0)  eyez = -eyez;
  394.         f = exp( -CC.Fog.Density * eyez );
  395.         f = CLAMP( f, 0.0F, 1.0F );
  396.         index[i] = (GLuint) ((GLfloat) index[i] + (1.0F-f) * CC.Fog.Index);
  397.      }
  398.      break;
  399.       case GL_EXP2:
  400.          for (i=0;i<n;i++) {
  401.         winz = (GLfloat) z[i] / (GLfloat) MAX_DEPTH;
  402.         ndcz = (winz - CC.Viewport.Tz) / CC.Viewport.Sz;
  403.         eyez = -d / (c+ndcz);
  404.         if (eyez < 0.0)  eyez = -eyez;
  405.         f = exp( -(CC.Fog.Density*CC.Fog.Density * eyez*eyez) );
  406.         f = CLAMP( f, 0.0F, 1.0F );
  407.         index[i] = (GLuint) ((GLfloat) index[i] + (1.0F-f) * CC.Fog.Index);
  408.      }
  409.      break;
  410.    }
  411.  
  412. }
  413.  
  414.